
package com.scalar.chiptrack.operations.process.actions;

import java.util.ArrayList;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.scalar.chiptrack.ChipTrackAction;
import com.scalar.chiptrack.commons.SessionKeys;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.chiptrack.operations.process.ProcessStep;
import com.scalar.chiptrack.operations.process.Upload;
import com.scalar.chiptrack.operations.process.VendorLocation;
import com.scalar.chiptrack.operations.process.dao.AssemblyProcessDAO;
import com.scalar.chiptrack.operations.process.dao.ProcessTrackDAO;
import com.scalar.chiptrack.operations.process.dao.ProductDao;
import com.scalar.chiptrack.operations.process.dao.VendorLocationDAO;
import com.scalar.chiptrack.operations.process.forms.AssemblyForm;
import com.scalar.chiptrack.operations.vendor.dao.VendorDAO;
import com.scalar.chiptrack.users.User;


public class AssemblyAction extends ChipTrackAction {

   private static final String STEP_TYPE = "Assembly";
   
   public ActionForward execute (ActionMapping mapping,
                                  ActionForm form,
                                  HttpServletRequest request,
                                  HttpServletResponse response)
                                  throws Exception {
		HttpSession session = request.getSession();
		User user = (User)session.getAttribute (SessionKeys.USER_KEY);
		if (user == null)
		{
			return (mapping.findForward ("login"));
		}
        String action = request.getParameter("action");
		HashMap errors = new HashMap();
        if ((action != null) && (action.equalsIgnoreCase("save"))) {

            AssemblyForm assemblyForm = (AssemblyForm) form;

            DBTransaction dbTransaction = null;
            boolean success = false;

            int processStepId = -1;
			processStepId = assemblyForm.getProcessStepId();

			// added by ravikanth on 18 Aug 2003 to check for duplicate part numbers in Product Map Table
			String[] partNumbers = new String[assemblyForm.getDupProductName().length+1];
			partNumbers[0] = assemblyForm.getProductName();
			for(int i=0; i < assemblyForm.getDupProductName().length ; i++)
			{
				partNumbers[i+1] = assemblyForm.getDupProductName()[i];
			}
			// added by ravikanth on 16 Sep 2003 
			// check for duplicates in Product_Map_Table
			String dupNames = ProductDao.checkDupInProductMapTable(partNumbers,processStepId,STEP_TYPE);
			
			//	to check for Duplicate names in Assembly_Track_Table
			/*if( dupNames.length() < 1 )
			{
				dupNames = AssemblyProcessDAO.checkProductNameInTrackTable(assemblyForm.getProductName(),assemblyForm.getProcessStepId());
			}*/
			if( dupNames.length() > 0 )
			{
				ArrayList vendorLocations = null;
				errors.put ("Part Number[s] Already exists ", dupNames );
                // changed by hareesh on 27th Septemebr 2003
                // -- START --
                vendorLocations = getAllVendorLocations(request);
                if(vendorLocations == null){
				    if(processStepId!=-1)
				    {
    					vendorLocations = VendorDAO.getAssemblyLocations (processStepId);
	    			}
		    		else
			    	{
				    	vendorLocations = VendorDAO.getAssemblyLocations();
				    }
                }
                // -- END --
				request.setAttribute (SessionKeys.ERROR_MESSAGES, errors);
				request.setAttribute( "assemblyForm" , assemblyForm );
				request.setAttribute( "vendorLocations" , vendorLocations );
				return ( mapping.findForward("failure") );
			}
			// upto here
            try
            {
                // start transaction
                dbTransaction = DBTransaction.getInstance();
                dbTransaction.begin();

				ArrayList locations = getVendorLocations(request);

				if(processStepId==-1){

					// Step 1
					// insert a record into Process_Step table and get the process step id
					processStepId = ProcessStep.getProcessStepID (dbTransaction,
																	assemblyForm.getStepName(),
																	STEP_TYPE, // Assembly
																	assemblyForm.getComments());

					//System.out.println ("process StepId = " + processStepId);

					// Step 2
					// Upload Procedure doc
					int procedureDocId = Upload.getProcedureDocID (dbTransaction,
																	  assemblyForm.getStepName(), // Assembly
																	  assemblyForm.getProcedureDocNumber(),
																	  assemblyForm.getProcedureDocFile());

					// Step 3
					// Upload Bonding diagram file
					int bondingDiagramId = Upload.getBondingDiagramDocID (dbTransaction,
																			 assemblyForm.getStepName(), // Assembly
																			 assemblyForm.getBondingDiagramDocNumber(),
																			 assemblyForm.getBondingDiagramDocFile());


					// Step 4
					// Upload Marking Spec file
					int markingSpecId = Upload.getMarkingSpecDocID (dbTransaction,
																		  assemblyForm.getStepName(), // Assembly
																		  assemblyForm.getMarkingSpec(),
																		  assemblyForm.getMarkingSpecFile());

					// STEP 4
					// insert a row in Assembly Table
					AssemblyProcessDAO.storeAssemblyProcessData (dbTransaction,
																processStepId,
																assemblyForm.getPackageID(),
																assemblyForm.getStandardUnitCost(),
																assemblyForm.getTargetYield(),
																assemblyForm.getLotScrapYieldLimit(),
																assemblyForm.getPoFrequency(),
																procedureDocId,
																bondingDiagramId,
																markingSpecId,
																assemblyForm.getDateCodeMarked());
                    // Step 4.1
                    // added by hareesh on 6th October 2003
                    // Change Status from Incomplete -> InProcess
                    ProcessTrackDAO.updateAssemblyTrack( dbTransaction, processStepId , assemblyForm.getTrackId() , "Inprocess" );

                    // Step 4.2
                    // added by hareesh on 26th August 2003
                    // To Update Product in Assembly Track Table, when Product Name is changed
                    // in Product Step
                    // -- START --
                       if ( ( assemblyForm.getProductName() !=null ) && ( assemblyForm.getOldProductName() !=null ) ) {

                         if( ! assemblyForm.getOldProductName().trim().equals( assemblyForm.getProductName().trim() ) ){

                            ProcessTrackDAO.updateAssemblyTrackProductName(dbTransaction,
                                                                        processStepId,
                                                                        assemblyForm.getTrackId(),
                                                                        assemblyForm.getProductName() );
                         }
                    }
                    // -- END --


					// Step 5
					// Store Product Table information
					ProductDao.saveProcessStepProduct (dbTransaction,
														  processStepId,
														  assemblyForm.getProductName(),
														  assemblyForm.getBaseProductId());

					// Step 6
					// Update nextStepID in the previousStepID row
					ProductDao.updateNextProcessStepId (dbTransaction, assemblyForm.getPreviousStepId(), processStepId);

					// Step 7
					// Save vendor locations

					if ((locations != null) && (locations.size() > 0)) {
						VendorLocationDAO.saveVendorLocations (dbTransaction, processStepId, locations.iterator());
					}
					
					// Added by ravikanth on 18 Sep 2003 
					// Step 8
					// Save Duplicate names into Product_Map_Table
					if( assemblyForm.getDupProductName() != null && assemblyForm.getDupProductName().length > 0 )
					{
						ProductDao.saveProductMap( dbTransaction , processStepId , assemblyForm.getDupProductName() , locations );
					}
				}
				else		//Updating Assembly Process
				{ 	
					//Step 1: Update Process Step Table
					ProcessStep.updateProcessStepID(dbTransaction,assemblyForm.getStepName(),STEP_TYPE,assemblyForm.getComments(),processStepId);

					// Step 2
					// Upload Procedure doc
					int procedureDocId = Upload.getProcedureDocID (dbTransaction,
																	  assemblyForm.getStepName(), // Assembly
																	  assemblyForm.getProcedureDocNumber(),
																	  assemblyForm.getProcedureDocFile());

					// Step 3
					// Upload Bonding diagram file
					int bondingDiagramId = Upload.getBondingDiagramDocID (dbTransaction,
																			 assemblyForm.getStepName(), // Assembly
																			 assemblyForm.getBondingDiagramDocNumber(),
																			 assemblyForm.getBondingDiagramDocFile());


					// Step 4
					// Upload Marking Spec file
					int markingSpecId = Upload.getMarkingSpecDocID (dbTransaction,
																		  assemblyForm.getStepName(), // Assembly
																		  assemblyForm.getMarkingSpec(),
																		  assemblyForm.getMarkingSpecFile());

					// STEP 5
					// Update Assembly Table
					AssemblyProcessDAO.updateAssemblyProcessData (dbTransaction,
																	processStepId,
																	assemblyForm.getPackageID(),
																	assemblyForm.getStandardUnitCost(),
																	assemblyForm.getTargetYield(),
																	assemblyForm.getLotScrapYieldLimit(),
																	assemblyForm.getPoFrequency(),
																	procedureDocId,
																	bondingDiagramId,
																	markingSpecId,
																	assemblyForm.getDateCodeMarked());
                    // Step 5.1
                    // added by hareesh on 26th August 2003
                    // To Update Product in Assembly Track Table, when Product Name is changed
                    // Product Step
                    // -- START --
                    if ( ( assemblyForm.getProductName() !=null ) && ( assemblyForm.getOldProductName() !=null ) ) {

                         if( ! assemblyForm.getOldProductName().trim().equals( assemblyForm.getProductName().trim() ) ){

                            ProcessTrackDAO.updateAssemblyTrackProductName(dbTransaction,
                                                                        processStepId,
                                                                        assemblyForm.getTrackId(),
                                                                        assemblyForm.getProductName() );
                         }
                    }
                    // -- END --

					// Step 6
					// Update Product Table information
					ProductDao.updateProcessStepProduct (dbTransaction,
														  processStepId,
														  assemblyForm.getProductName(),
														  assemblyForm.getBaseProductId());


					// Step 7
					// Delete and Save vendor locations
					VendorLocationDAO.deleteVendorLocations(dbTransaction,processStepId);
					if ((locations != null) && (locations.size() > 0)) {
						VendorLocationDAO.saveVendorLocations (dbTransaction, processStepId, locations.iterator());
					}

					// Added by ravikanth on 18 Sep 2003 
					// Step 8
					// Save Duplicate names into Product_Map_Table
					if( assemblyForm.getDupProductName() != null && assemblyForm.getDupProductName().length > 0 )
					{
						ProductDao.saveProductMap( dbTransaction , processStepId , assemblyForm.getDupProductName() , locations );
					}	

                }
                // End transaction

                success = true;
            }

            catch (Exception e) {
                e.printStackTrace();
            }

            finally {
                // Rollback or Commit the Transaction

                if (success == true) {
                    dbTransaction.commit();
                }
                else {
                    dbTransaction.rollback();
                }
            }


            // If sucessful, go to transport_locations page
            if (success == true) {

                request.setAttribute ("processStepId", processStepId+"");                         //
                request.setAttribute ("previousStepId", assemblyForm.getPreviousStepId()+"");  // to be used in transport_locations page
                request.setAttribute ("trackId", assemblyForm.getTrackId()+"");                  //
		        request.setAttribute("baseProductId", assemblyForm.getBaseProductId()+"");      //
                request.setAttribute ("comingFrom", "ASSEMBLY");                                 //

                return (mapping.findForward("success"));
            }

            // else send the user back to test page
            // Added by hareesh on 27th September 2003
            // -- START --
            ArrayList vendorLocations = null;
            vendorLocations =  getAllVendorLocations(request);
            if(vendorLocations == null){
                if(processStepId!=-1)
				    {
    					vendorLocations = VendorDAO.getAssemblyLocations (processStepId);
	    			}
		    		else
			    	{
				    	vendorLocations = VendorDAO.getAssemblyLocations();
				    }
            }
            request.setAttribute ("vendorLocations", vendorLocations);
            // -- END --
            return (mapping.findForward("failure"));
        }


        int processStepId = Integer.parseInt (request.getParameter ("processStepID"));
        int trackId = -1;
        String trackIdStr = request.getParameter ("trackID");
        if ((trackIdStr != null) && (trackIdStr.trim().length() != 0)) {
            trackId = Integer.parseInt (trackIdStr);
        }

        AssemblyForm assemblyForm = null;
        ArrayList vendorLocations = null;

        if (processStepId == -1) {  // New

            String stepName = request.getParameter ("stepName");
            String productName = request.getParameter ("productName");
            int baseProductId = Integer.parseInt (request.getParameter ("baseProductID"));
            int previousStepId = Integer.parseInt (request.getParameter ("previousStepID"));

            assemblyForm = AssemblyProcessDAO.loadAssemblyProcessData (previousStepId);
            if (assemblyForm == null) {
                assemblyForm = new AssemblyForm();
            }

            assemblyForm.setProductName (productName);
            assemblyForm.setBaseProductId (baseProductId);
            assemblyForm.setPreviousStepId (previousStepId);
            assemblyForm.setTrackId (trackId);

            // Added by hareesh on 2nd September 2003
             assemblyForm.setOldProductName(productName);

            vendorLocations = VendorDAO.getAssemblyLocations();
        }
        else {  // Existing
            assemblyForm = AssemblyProcessDAO.loadAssemblyProcessData (processStepId);
            assemblyForm.setTrackId (trackId);
            assemblyForm.setProcessStepId (processStepId);

            vendorLocations = VendorDAO.getAssemblyLocations (processStepId);
        }

        request.setAttribute ("vendorLocations", vendorLocations);
        request.setAttribute ("assemblyForm", assemblyForm);

        return (mapping.findForward ("show"));
    }


    private ArrayList getVendorLocations (HttpServletRequest request) {

        ArrayList vendorLocations = new ArrayList();

        String[] locationName = request.getParameterValues("locationName");
        if (locationName == null) {
            return null;
        }

	String[] priority = request.getParameterValues("priority");
	String[] locationID = request.getParameterValues("locationID");;
	String[] split = request.getParameterValues("split");
	String[] capacityWeek = request.getParameterValues("capacityWeek");
	String[] normalCost = request.getParameterValues("normalCost");
	String[] expressCost = request.getParameterValues("expressCost");
	String[] normalCycleTime = request.getParameterValues("normalCycleTime");
	String[] expressCycleTime = request.getParameterValues("expressCycleTime");
    String[] expectedYield = request.getParameterValues("expectedYield");
    String[] rawLevelMin = request.getParameterValues("rawLevelMin");
    String[] rawLevelMax = request.getParameterValues("rawLevelMax");

        VendorLocation location = null;
        String select = null;
        String rawMaterialSource = null;

        for (int i=0; i<locationName.length; i++) {

            select = request.getParameter("select_"+i);
            if (select != null) {    // check if this row was enabled by the user or not
                                                                    // save only if its enabled

                // Changed by hareesh on 25th August 2003
                // -- START --
                /*location = new VendorLocation (priority[i],
                                                 locationName[i],
                                                 locationID[i],
                                                 split[i],
                                                 capacityWeek[i],
                                                 Float.parseFloat(normalCost[i]),
                                                 Float.parseFloat(expressCost[i]),
                                                 normalCycleTime[i],
                                                 expressCycleTime[i]);*/

                location = new VendorLocation();
                location.setPriority( ( priority[i] != null && priority[i].trim().length() != 0) ? priority[i] : "0" );
                location.setLocationName( locationName[i] );
                location.setLocationID( locationID[i] );
                location.setSplit( ( split[i] != null && split[i].trim().length() != 0) ? split[i] : "0" );
                location.setCapacityWeek( ( capacityWeek[i] != null && capacityWeek[i].trim().length() != 0) ? capacityWeek[i] : "0" );
                location.setNormalCost( Float.parseFloat ( ( normalCost[i] != null && normalCost[i].trim().length() != 0) ? normalCost[i] : "0.0" ) );
                location.setExpressCost( Float.parseFloat( expressCost[i] != null && expressCost[i].trim().length() != 0 ? expressCost[i] : "0.0" ) ) ;
                location.setNormalCycleTime(( normalCycleTime[i] != null && normalCycleTime[i].trim().length() != 0) ? normalCycleTime[i] : "0" );
                location.setExpressCycleTime(( expressCycleTime[i] != null && expressCycleTime[i].trim().length() != 0) ? expressCycleTime[i] : "0"  );

                location.setSelect (select);
                //location.setExpectedYield (Float.parseFloat (expectedYield[i]));
                location.setExpectedYield(Float.parseFloat( expectedYield[i] != null && expectedYield[i].trim().length() != 0 ? expectedYield[i] : "0.0" ) );

                //location.setRawLevelMin (rawLevelMin[i]);
                //location.setRawLevelMax (rawLevelMax[i]);

                rawMaterialSource = request.getParameter ("rawMaterialSource_"+i);
                if ((rawMaterialSource == null) || (rawMaterialSource.trim().length() == 0)) {
                    location.setRawMaterialSource (false);
                    location.setRawLevelMin ("0");
                    location.setRawLevelMax ("0");
                }
                else {
                    location.setRawMaterialSource (true);
                    location.setRawLevelMin ( ( rawLevelMin[i] != null && rawLevelMin[i].trim().length() != 0) ? rawLevelMin[i] : "0" );
                    location.setRawLevelMax ( ( rawLevelMax[i] != null && rawLevelMax[i].trim().length() != 0) ? rawLevelMax[i] : "0" );
                }

                vendorLocations.add (location);
                // -- END --
            }
        }

        return vendorLocations;
    }

    // Added by hareesh on 27th Stepemeber 2003
    // -- START --
    private ArrayList getAllVendorLocations (HttpServletRequest request) {

        ArrayList vendorLocations = new ArrayList();

        String[] locationName = request.getParameterValues("locationName");
        if (locationName == null) {
            return null;
        }

        String[] priority = request.getParameterValues("priority");
        String[] locationID = request.getParameterValues("locationID");;
        String[] split = request.getParameterValues("split");
        String[] capacityWeek = request.getParameterValues("capacityWeek");
        String[] normalCost = request.getParameterValues("normalCost");
        String[] expressCost = request.getParameterValues("expressCost");
        String[] normalCycleTime = request.getParameterValues("normalCycleTime");
        String[] expressCycleTime = request.getParameterValues("expressCycleTime");
        String[] expectedYield = request.getParameterValues("expectedYield");
        String[] rawLevelMin = request.getParameterValues("rawLevelMin");
        String[] rawLevelMax = request.getParameterValues("rawLevelMax");

        VendorLocation location = null;
        String select = null;
        String rawMaterialSource = null;

        for (int i=0; i<locationName.length; i++) {

            select = request.getParameter("select_"+i);
           if (select != null) {    // check if this row was enabled by the user or not
                 select = "on";                    // save only if its enabled
            }else {
                  select = "";
            }
            location = new VendorLocation();
            location.setPriority( ( priority[i] != null && priority[i].trim().length() != 0) ? priority[i] : "0" );
            location.setLocationName( locationName[i] );
            location.setLocationID( locationID[i] );
            location.setSplit( ( split[i] != null && split[i].trim().length() != 0) ? split[i] : "0" );
            location.setCapacityWeek( ( capacityWeek[i] != null && capacityWeek[i].trim().length() != 0) ? capacityWeek[i] : "0" );
            location.setNormalCost( Float.parseFloat ( ( normalCost[i] != null && normalCost[i].trim().length() != 0) ? normalCost[i] : "0.0" ) );
            location.setExpressCost( Float.parseFloat( expressCost[i] != null && expressCost[i].trim().length() != 0 ? expressCost[i] : "0.0" ) ) ;
            location.setNormalCycleTime(( normalCycleTime[i] != null && normalCycleTime[i].trim().length() != 0) ? normalCycleTime[i] : "0" );
            location.setExpressCycleTime(( expressCycleTime[i] != null && expressCycleTime[i].trim().length() != 0) ? expressCycleTime[i] : "0"  );

            location.setSelect (select);
            location.setExpectedYield(Float.parseFloat( expectedYield[i] != null && expectedYield[i].trim().length() != 0 ? expectedYield[i] : "0.0" ) );
            rawMaterialSource = request.getParameter ("rawMaterialSource_"+i);
            if ((rawMaterialSource == null) || (rawMaterialSource.trim().length() == 0)) {
                location.setRawMaterialSource (false);
                location.setRawLevelMin ("0");
                location.setRawLevelMax ("0");
            }
            else {
                location.setRawMaterialSource (true);
                location.setRawLevelMin ( ( rawLevelMin[i] != null && rawLevelMin[i].trim().length() != 0) ? rawLevelMin[i] : "0" );
                location.setRawLevelMax ( ( rawLevelMax[i] != null && rawLevelMax[i].trim().length() != 0) ? rawLevelMax[i] : "0" );
            }

            vendorLocations.add (location);
        }

        return vendorLocations;
    }
    // -- START --
}